package com.project.controller.auth;

import com.alibaba.fastjson.JSON;
import com.project.controller.base.BaseController;
import com.project.model.User;
import com.project.service.EmailService;
import com.project.service.UserService;
import com.project.util.MyJWT;
import com.project.util.Util;
import com.project.util.encode.AES256;
import org.mindrot.jbcrypt.BCrypt;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;


@Controller
@RequestMapping("auth")
public class AuthController extends BaseController {
    @Autowired
    UserService userService;
    @Autowired
    EmailService emailService;

    @RequestMapping(value = "login", method = RequestMethod.GET)
    public String login() {
        return "home/auth/login";
    }

    @ResponseBody
    @PostMapping("login")
    public String doLogin(HttpServletRequest request, HttpServletResponse response) {
        String email = request.getParameter("email");
        String password = request.getParameter("password");
        boolean rememberMe = Boolean.parseBoolean(request.getParameter("rememberMe"));
        Map<String, Object> responseData = new HashMap<>();
        User user = userService.selectByEmail(email);
        if (user != null) {
            boolean passwordOk = BCrypt.checkpw(password, user.getPassword());
            if (passwordOk) {
                String jwtSignature = UUID.randomUUID().toString();
                userService.deleteJwtSignature(user.getId());
                user.setJwtSignature(jwtSignature);
                userService.updateUser(user);
                try {
                    String jwtToken = MyJWT.createJwt(user.getId(), user.getEmail(), "stbbbs", jwtSignature, 60 * 60 * 24 * 14);
                    Cookie jwtCookie = new Cookie("accessToken", jwtToken);
                    if (rememberMe == true) {
                        jwtCookie.setMaxAge(60 * 60 * 24 * 14);
                    }
                    jwtCookie.setPath("/");
                    response.addCookie(jwtCookie);
                } catch (Exception e) {
                    e.printStackTrace();
                }

                responseData.put("status", true);
                responseData.put("msg", "登录成功");
            } else {
                responseData.put("passwordError", true);
                responseData.put("msg", "密码不正确");
            }
        } else {
            responseData.put("emailError", true);
            responseData.put("msg", "该邮箱不存在");
        }
        return JSON.toJSONString(responseData);
    }

    @GetMapping("loginUseCode")
    public String loginUseCode() {
        return "home/auth/loginUseCode";
    }

    @ResponseBody
    @PostMapping("loginUseCode")
    public String doLoginUseCode(HttpServletRequest request, HttpServletResponse response) {
        String email = request.getParameter("email");
        String code = request.getParameter("code");
        boolean rememberMe = Boolean.parseBoolean(request.getParameter("rememberMe"));
        Cookie codeCookie = Util.getCookieByName(request, "verifyCode");
        String requestCode = null;
        if (codeCookie != null) {
            requestCode = AES256.decrypt(codeCookie.getValue(), appKey);
        }
        Map<String, Object> responseData = new HashMap<>();
        User user = userService.selectByEmail(email);
        if (user != null) {
            if (code.equals(requestCode)) {
                request.getSession().setAttribute("user", user);
                if (rememberMe == true) {
                    addRememberToken(user, response);
                }
                responseData.put("status", true);
                responseData.put("msg", "登录成功");
                Util.delCookie(response, "verifyCode", null);
            } else {
                responseData.put("codeError", true);
                responseData.put("msg", "验证码不正确");
            }
        } else {
            responseData.put("emailError", true);
            responseData.put("msg", "该邮箱不存在");
        }
        return JSON.toJSONString(responseData);
    }

    /**
     * 把记住我的token添加到cookie中
     *
     * @param user
     * @param response
     */
    public void addRememberToken(User user, HttpServletResponse response) {
        String uuid = UUID.randomUUID().toString();
        user.setRememberToken(uuid);
        userService.setUserRememberToken(user);
        Cookie rememberToken = new Cookie("rememberToken", uuid);
        rememberToken.setMaxAge(60 * 60 * 24 * 30);
        rememberToken.setPath("/");
        response.addCookie(rememberToken);
    }

    @RequestMapping("logout")
    public void logout(HttpServletRequest request, HttpServletResponse response) {
        User user = userService.getCurrentUser(request);
        userService.deleteJwtSignature(user.getId());
        Util.delCookie(response, "accessToken", "/");
        response.setStatus(303);
        response.setHeader("Location","/auth/login");
    }

    @GetMapping("register")
    public String register() {
        return "home/auth/register";
    }

    @ResponseBody
    @PostMapping("register")
    public String doRegister(
            @Valid User user,
            BindingResult result,
            HttpServletRequest request,
            HttpServletResponse response
    ) {
        if (result.hasErrors()) {
            return result.getAllErrors().get(0).getDefaultMessage();
        }
        Map<String, Object> map = new HashMap<>();
        User record = userService.selectByEmail(user.getEmail());
        if (record != null) {
            map.put("emailStatus", false);
            map.put("msg", "该邮箱已经存在了");
            return JSON.toJSONString(map);
        }
        Cookie registryCodeCookie = Util.getCookieByName(request, "verifyCode");
        if (registryCodeCookie == null) {
            map.put("codeStatus", false);
            map.put("msg", "验证码不正确");
            return JSON.toJSONString(map);
        }
        String registryCode = AES256.decrypt(registryCodeCookie.getValue(), appKey);
        if (!user.getCode().equals(registryCode)) {
            map.put("codeStatus", false);
            map.put("msg", "验证码不正确");
            return JSON.toJSONString(map);
        }
        if (userService.addUser(user) > 0) {
            Util.delCookie(response, "verifyCode", null);
        } else {
            map.put("failure", true);
            map.put("msg", "注册失败，请重新再试");
            return JSON.toJSONString(map);
        }
        map.put("success", true);
        User newUser = userService.selectByEmail(user.getEmail());
        request.getSession().setAttribute("userId", newUser.getId());
        return JSON.toJSONString(map);
    }

    @ResponseBody
    @PostMapping("checkEmailExist")
    public String checkEmailExist(@RequestParam String email) {
        User user = userService.selectByEmail(email);
        Map<String, Object> map = new HashMap<>();
        map.put("exist", false);
        if (user != null) {
            map.put("exist", true);
        }
        return JSON.toJSONString(map);
    }

    @ResponseBody
    @PostMapping("getCode")
    public void getCode(@RequestParam(value = "email") String email, HttpServletResponse response) {
        String code = String.valueOf(Util.getRandomNumber(6));
        emailService.send(email, "您的验证码" + code, "您的验证码为:" + code + "  请勿告诉他人哦!");
        Cookie registryCookie = new Cookie("verifyCode", AES256.encrypt(code, appKey));
        registryCookie.setMaxAge(60 * 60);
        response.addCookie(registryCookie);
    }

    @RequestMapping("403")
    public String forbidden() {
        return "home/auth/403";
    }
}
